type OwnEventValue = (...params: any) => void
export type OwnEvents = Record<string, any>
export type ObjectType = Record<string, any>

// 初始化
export default function ownEventsInit(): OwnEvents {
  const events: OwnEvents = {}

  return new Proxy(events, {
    set(obj, key: string, value: OwnEventValue) {
      if (obj.hasOwnProperty(key) && Array.isArray(obj[key])) {
        obj[key].push(value)
      } else {
        obj[key] = [value]
      }

      return true
    },
    get(obj, key) {
      return obj.hasOwnProperty(key) ? obj[key as keyof typeof obj] : undefined
    }
  })
}

// 内部使用的事件名
const ownEventName = [
  'onGridReady',
  'onBodyScrollEnd'
]

// 绑定事件处理 - 避免 组件外部绑定事件 与 内部绑定事件 无法同时使用
export function eventCall(res: ObjectType): void {
  /*
  * 当 用户传入了 onBodyScrollEnd，组件内部也使用了 onBodyScrollEnd 时
  *
  * 通过 mergeProps 合并后 得到的 onBodyScrollEnd 是一个 数组
  *
  * 此处 重写 onBodyScrollEnd，
  * 在其回调中调用 传入的每一个 onBodyScrollEnd，确保所有 onGridReady 都会被触发
  *  */
  ownEventName.forEach(eventName => {
    const events = res[eventName]

    if (Array.isArray(events)) {
      res[eventName] = (...arg: any[]) => {
        events.forEach(fn => {
          fn(...arg)
        })
      }
    }
  })
}